package org.easy.tool.common;

import cn.hutool.poi.word.Word07Writer;
//import com.microsoft.schemas.vml.CTShape;
//import com.spire.doc.Document;
//import com.spire.doc.FileFormat;
//import com.spire.doc.PictureWatermark;
//import com.spire.doc.Section;
//import com.spire.doc.documents.*;
//import com.spire.doc.fields.DocPicture;
//import com.spire.doc.fields.TextRange;
//import org.apache.poi.hwpf.HWPFDocument;
import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;
import org.apache.poi.xwpf.usermodel.*;
import org.apache.xmlbeans.XmlToken;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDocument1;
import org.springframework.beans.factory.annotation.Value;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.regex.Pattern;

/**
 * @author Valley
 * Created by Valley on 2023/7/26 14:03
 */
public class WordUtil {

    //在controller或者service层用
    @Value("${download.temp.dir}")
    String downloadDir;


    /**
     * 功能：读取word文件每一行内容
     */
    public static List<String> read07(String filePath) throws Exception {
        List<String> contents = new ArrayList<>();
        FileInputStream fis = new FileInputStream(filePath);
        XWPFDocument document = new XWPFDocument(fis);
        List<XWPFParagraph> paragraphs = document.getParagraphs();
        for (XWPFParagraph paragraph : paragraphs) {
            List<XWPFRun> runs = paragraph.getRuns();
            if (runs != null && !runs.isEmpty()) {
                String line = runs.get(0).getText(0);
                contents.add(line);
            }
        }
        fis.close();
        return contents;
    }

    /**
     * 功能：给word报告添加水印，每一页加一个水印,自定义页面配置，只能加一个水印，不太好使
     */
    public static void addPageWatermark(String originFile, String outFile, String watermark, LinkedHashMap<String, Object> style) throws Exception {
        //输入的docx文档
        InputStream in = Files.newInputStream(new File(originFile).toPath());
        XWPFDocument doc = new XWPFDocument(in);
        //创建文本段落
        XWPFHeaderFooterPolicy headerFooterPolicy = doc.getHeaderFooterPolicy();//获取页面页脚
        if (headerFooterPolicy == null) headerFooterPolicy = doc.createHeaderFooterPolicy();//如果没有页眉页脚则创建
        headerFooterPolicy.createWatermark(watermark);//设置水印显示的内容
        XWPFHeader header = headerFooterPolicy.getHeader(XWPFHeaderFooterPolicy.DEFAULT);
        XWPFParagraph paragraph = header.getParagraphArray(0);
        org.apache.xmlbeans.XmlObject[] xmlArr = paragraph.getCTP().getRArray(0).getPictArray(0).selectChildren(
                new javax.xml.namespace.QName("urn:schemas-microsoft-com:vml", "shape"));
        if (xmlArr.length > 0) {
            com.microsoft.schemas.vml.CTShape ctshape = (com.microsoft.schemas.vml.CTShape) xmlArr[0];
            //设置水印的颜色
            String color = (String) style.get("color");
            if (color == null) color = "#f6f6f6";
            ctshape.setFillcolor(color);
            //设置自定义水印的样式，setStyle()方法中需传入样式字符串
            ctshape.setStyle(getWaterMarkStyle(ctshape.getStyle(), style));
        }

        doc.write(Files.newOutputStream(Paths.get(outFile)));
        doc.close();
    }

    /**
     * 功能：给word报告添加水印，每一页加一个水印,默认配置
     */
    public static void addPageWatermark(String originFile, String outFile, String watermark) throws Exception {
        addPageWatermark(originFile, outFile, watermark, new LinkedHashMap<>());
    }

    /**
     * 修改水印样式的方法
     *
     * @param styleStr    之前的水印样式
     * @param styleConfig 需要改成的样式
     * @return 返回新的修改好的水印样式
     */
    public static String getWaterMarkStyle(String styleStr, LinkedHashMap<String, Object> styleConfig) {
        for (String key : styleConfig.keySet()) {
            if (styleStr.contains(key)) {
                //把拿到的样式用";"切割，切割后保存到数组中
                Pattern match = Pattern.compile(";");
                String[] strList = match.split(styleStr);
                //遍历保存的数据，找到原始样式，将原始样式改为参数传入的样式
                for (String str : strList) {
                    if (str.startsWith(key + ":")) {
                        String outStr = key + ":" + styleConfig.get(key);
                        styleStr = styleStr.replace(str, outStr);
                        break;
                    }
                }
            } else {
                styleStr = styleStr + ";" + key + ":" + styleConfig.get(key);
            }
        }
        //返回改好的样式
        return styleStr;
    }

    /**
     * 功能：给word报告添加水印，水印加在段落里
     */
    public static void addParaWatermark(String originFile, String outFile, String watermark) throws Exception {
        // 创建一个Word文档对象
        XWPFDocument document = new XWPFDocument(Files.newInputStream(Paths.get(originFile)));
        //TODO 这一句可以获取word页数
        //int pages = document.getProperties().getExtendedProperties().getUnderlyingProperties().getPages()
        // 创建一个空白段落对象，并将其添加到文档中
        List<XWPFParagraph> paragraphs = document.getParagraphs();
        for (XWPFParagraph paragraph : paragraphs) {
            // 创建一个水印对象，并将其添加到段落中
            XWPFRun run = paragraph.createRun();
            run.setText(watermark);
            run.setFontSize(50);
            run.setColor("D3D3D3"); // 灰色
            run.setBold(true);
            run.setStrike(true);
            run.setUnderline(UnderlinePatterns.SINGLE);
            run.setVerticalAlignment(ParagraphAlignment.CENTER.name());
        }
        // 将文档保存到指定的文件路径中
        FileOutputStream out = new FileOutputStream(outFile);
        document.write(out);
        out.close();
        document.close();
    }


    /**
     * 功能：在指定位置添加图片
     */
    public static void addImg(String originDoc, String outDoc) throws Exception {
        FileInputStream fileInputStream = new FileInputStream(originDoc);//读取目标文件路径
        XWPFDocument docx = new XWPFDocument(fileInputStream);
        XWPFParagraph par = docx.createParagraph();
        XWPFRun run = par.createRun();
        //第一个图片
        BufferedImage image = ExcelUtil.createWatermarkImage("测试一下");
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        ImageIO.write(image, "png", os);
        run.addPicture(new ByteArrayInputStream(os.toByteArray()), org.apache.poi.xwpf.usermodel.Document.PICTURE_TYPE_PNG, "", 6061200, 3858000);// 宽  高
        run.setText("图1");//插入图片底部文字
        run.setFontSize(13);
        run.setCapitalized(true);
        //第二个图片
        BufferedImage image2 = ExcelUtil.createWatermarkImage("第二个水印");
        ByteArrayOutputStream os2 = new ByteArrayOutputStream();
        ImageIO.write(image2, "png", os2);
        run.addPicture(new ByteArrayInputStream(os2.toByteArray()), org.apache.poi.xwpf.usermodel.Document.PICTURE_TYPE_PNG, "", 6061200, 3858000);// 宽  高
        run.setText("图2");
        run.setFontSize(13);
        run.setCapitalized(true);

        FileOutputStream out = new FileOutputStream(outDoc);
        docx.write(out);
        out.close();
        os.close();
        os2.close();
        System.out.println("sucess!!");
    }

//    /**
//     * 功能：使用Spire对每一页添加一个图片
//     */
//    public static void addImgSpire(String inDocPath, String imgPath, String outDocPath) {
//        //加载示例文档
//        Document doc = new Document();
//        doc.loadFromFile(inDocPath);
//
//        //创建一个 PictureWatermark 实例
//        PictureWatermark picture = new PictureWatermark();
//
//        //设置图像水印格式
//        picture.setPicture(imgPath);
//        picture.setScaling(100);
//        picture.isWashout(false);
//
//        //将图像水印添加到示例文档中
//        doc.setWatermark(picture);
//
//        //保存文件
//        doc.saveToFile(outDocPath, FileFormat.Docx);
//        doc.dispose();
//    }

//    /**
//     * 功能：在指定位置添加印章签名
//     */
//    public static void signDoc(String inDocPath, String imgPath, String outDocPath) {
//        //加载示例文档
//        Document doc = new Document();
//        doc.loadFromFile(inDocPath);
//        //获取指定段落
//        Section section = doc.getSections().get(0);
//        Paragraph paragraph = section.getParagraphs().get(6);
//        //添加电子章图片
//        DocPicture picture = paragraph.appendPicture(imgPath);
//        //指定电子章位置
//        picture.setHorizontalPosition(180f);
//        picture.setVerticalPosition(180f);
//        //设置电子章大小
//        picture.setWidth(150);
//        picture.setHeight(150);
//        //设置图片浮于文字上方
//        picture.setTextWrappingStyle(TextWrappingStyle.Behind);
//        //保存文档
//        doc.saveToFile(outDocPath, FileFormat.Docx);
//        doc.dispose();
//    }


    /**
     * 功能：导出Word，参数为列表，仅支持写文字
     */
    public static boolean write07(String dest, String title, List<String> contexts) {
        Word07Writer writer = cn.hutool.poi.word.WordUtil.getWriter();
        // 添加段落（标题）
        writer.addText(new Font("宋体", Font.PLAIN, 10), "");
        writer.addText(ParagraphAlignment.CENTER, new Font("方正小标宋简体", Font.BOLD, 20), title);
        writer.addText(new Font("宋体", Font.PLAIN, 10), "");
        // 添加段落（正文）
        for (String context : contexts) {
            writer.addText(new Font("宋体", Font.PLAIN, 12), context);
        }
        // 写出到文件
        writer.flush(FileUtil.file(dest));
        // 关闭
        writer.close();
        return true;
    }

//    /**
//     * 功能：Java 用图片替换 Word 文档中的特定文本
//     */
//    public static void replaceStrByImg(String docPath, String imgPath, String outDocPath) {
//        //加载示例文档
//        Document document = new Document();
//        document.loadFromFile(docPath);
//
//        //查找文档中的字符串“成都冰蓝科技有限公司”
//        Pattern pattern = Pattern.compile("^http.*");
//        TextSelection[] selections = document.findPatternInLine(pattern);
//
//        //用图片替换文字
//        int index = 0;
//        TextRange range = null;
//        for (Object obj : selections) {
//            TextSelection textSelection = (TextSelection) obj;
//            DocPicture pic = new DocPicture(document);
//            pic.loadImage(imgPath);
//            range = textSelection.getAsOneRange();
//            index = range.getOwnerParagraph().getChildObjects().indexOf(range);
//            range.getOwnerParagraph().getChildObjects().insert(index, pic);
//            range.getOwnerParagraph().getChildObjects().remove(range);
//        }
//
//        //保存文档
//        document.saveToFile(outDocPath, FileFormat.Docx);
//    }
//
//    /**
//     * 功能：使用SpireDoc生成word，支持识别文字和图片，后续支持更多格式，推荐使用该方法
//     */
//    public static void write(String dest, String title, List<String> context, String imgDir) throws Exception {
//
//        //创建Word文档
//        Document document = new Document();
//        //添加一个section
//        Section section = document.addSection();
//        Paragraph titlePara = section.addParagraph();
//        //设置标题
//        titlePara.appendText(title);
//        ParagraphStyle style1 = new ParagraphStyle(document);
//        style1.setName("titleStyle");
//        style1.getCharacterFormat().setBold(true);
//        style1.getCharacterFormat().setTextColor(Color.BLUE);
//        style1.getCharacterFormat().setFontName("宋体");
//        style1.getCharacterFormat().setFontSize(24f);
//        //设置第一个段落的对齐方式
//        titlePara.getFormat().setHorizontalAlignment(HorizontalAlignment.Center);
//        document.getStyles().add(style1);
//        titlePara.applyStyle("titleStyle");
//        for (String s : context) {
//            try {
//                //添加三个段落至section
//                Paragraph para = section.addParagraph();
//                //图片这部分不能直接用，需要根据实际业务修改
//                if (s.startsWith("http")) {
//                    String imgPath = "";
//                    String[] split = s.split("/");
//                    String fileName = split[split.length - 1];
//                    if (fileName.contains(".")) {
//                        //TODO 图片保存路径
//                        //String path = downloadDir + fileName;
//                        String path = fileName;
//                        FileUtil.mkDirs(path);
//                        HttpUtil.download(s, path);
//                        imgPath = path;
//                    } else {
//                        //TODO 特殊处理
//                        //String filePath = fileService.getById(fileName).getFilePath();
//                        //imgPath = filePath;
//                    }
//                    DocPicture picture = new DocPicture(document);
//                    picture.loadImage(imgPath);
//                    picture.setHeight(240);
//                    picture.setWidth(240);
//                    para.getChildObjects().insert(0, picture);
//                } else {
//                    para.appendText(s);
//                }
//                para.getFormat().setAfterSpacing(20f);
//            } catch (Exception e) {
//                e.printStackTrace();
//            }
//        }
//        FileUtil.mkDirs(dest);
//        document.saveToFile(dest, FileFormat.Docx);
//    }

    /**
     * 功能：导出Word，参数为列表，添加副标题
     */
    public static boolean write07(String dest, String title, List<String> contexts, List<String> subHead) {
        Word07Writer writer = cn.hutool.poi.word.WordUtil.getWriter();
        // 添加段落（标题）
        writer.addText(new Font("宋体", Font.PLAIN, 10), "");
        writer.addText(ParagraphAlignment.CENTER, new Font("方正小标宋简体", Font.BOLD, 20), title);
        writer.addText(new Font("宋体", Font.PLAIN, 10), "");

        //添加副标题
        for (String s : subHead) {
            writer.addText(ParagraphAlignment.LEFT, new Font("宋体", Font.ITALIC, 12), s);
        }

        // 添加段落（正文）
        for (String context : contexts) {
            writer.addText(new Font("宋体", Font.PLAIN, 12), context);
        }
        // 写出到文件
        writer.flush(FileUtil.file(dest));
        // 关闭
        writer.close();
        return true;
    }

    /**
     * 功能：
     */
    public static void insertImg() {

    }

    /**
     * 功能：删除word空白页面
     */
    public static void deleteBlankPage(String originPath, String outPath) throws Exception {
        FileInputStream fis = new FileInputStream(originPath);
        XWPFDocument document = new XWPFDocument(fis);
        boolean delete = false;
        //删除段落
        List<XWPFParagraph> paragraphs = document.getParagraphs();
        List<Integer> deleteList = new ArrayList<>();
        for (int i = 0; i < paragraphs.size(); i++) {
            String text = paragraphs.get(i).getText();
            if (text.contains("elete")) {
                int paragraphPos = document.getParagraphPos(i);
                deleteList.add(paragraphPos);
            }
        }
        List<XWPFTable> tables = document.getTables();
        //删除表格
        for (int i = 0; i < tables.size(); i++) {
            XWPFTable xwpfTable = tables.get(i);
            String text = xwpfTable.getText();
            if (text.contains("elete")) {
                int tablePos = document.getTablePos(i);
                deleteList.add(tablePos);
            }
        }
        int count = 0;
        for (Integer integer : deleteList) {
            document.removeBodyElement(integer - count);
            count++;
        }
        FileOutputStream fos = new FileOutputStream(outPath);
        document.write(fos);
        fis.close();
        fos.close();
    }

    /**
     * 功能：word添加水印，平铺效果，只支持文字
     */
    public static void addFlatWaterMark(String originPath, String outPath, String text, LinkedHashMap<String, Object> styleMap) throws Exception {
        FileInputStream fis = new FileInputStream(originPath);
        XWPFDocument document = new XWPFDocument(fis);
        XWPFHeaderFooterPolicy headerFooterPolicy = document.getHeaderFooterPolicy();
        if (headerFooterPolicy == null) {
            //兼容处理
            headerFooterPolicy = document.createHeaderFooterPolicy();
        }
        //调用API添加水印，效果不好为水平居中
        headerFooterPolicy.createWatermark(text);
        //处理后续文档更新水印逻辑
//        XWPFHeader header = headerFooterPolicy.getHeader(XWPFHeaderFooterPolicy.DEFAULT);
//        XWPFParagraph paragraph;
//        paragraph = header.getParagraphArray(0);
//        //设置水印样式和位置，保持倾斜角度更好看和实用
//        paragraph.getCTP().newCursor();
//        org.apache.xmlbeans.XmlObject[] xmlobjects = paragraph.getCTP().getRArray(0).getPictArray(0).selectChildren(
//                new javax.xml.namespace.QName("urn:schemas-microsoft-com:vml", "shape"));
//        if (xmlobjects.length > 0) {
//            CTShape ctshape = (CTShape) xmlobjects[0];
//            ctshape.setFillcolor("#C0C0C0");
//            ctshape.setStyle(getWaterMarkStyle(ctshape.getStyle(), styleMap));
//            //ctshape.setStyle(ctshape.getStyle() + ";rotation:315");
//        }
        FileOutputStream fos = new FileOutputStream(outPath);
        document.write(fos);
        fis.close();
        fos.close();

    }

}
